package controllers
/*********************************************************/
/************本文档中的程序用于终端设备的websocket链接*********/
/*********************version:1.0*************************/
/****Copyright (c) 2014年 许剑华. All rights reserved******/
/*********************************************************/
import (
	"encoding/json"
	"net/http"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/gorilla/websocket"
	."smart_home/lib"
	"time"
	//"github.com/astaxie/beego/logs"
	//"github.com/beego/samples/WebIM/models"
)

// WebSocketController handles WebSocket requests.
type WebSocketController struct {
	beego.Controller
}
var ConnStruct = make(map[string] int)


// 设备加入到服务器中
func (this *WebSocketController) DeviceJoin() {
	mac := this.GetString("mac")     //获取连接中的mac
	if len(mac) == 0 {
		respone_json := Reg_Log_Type{PARA_ERROR, INVALID, INVALID}
		this.Data["json"] = &respone_json
		this.ServeJson();
		return
	}
	// Upgrade from http request to WebSocket.
	ws, err := websocket.Upgrade(this.Ctx.ResponseWriter, this.Ctx.Request, nil, 2048, 2048)

	if _, ok := err.(websocket.HandshakeError); ok {
		http.Error(this.Ctx.ResponseWriter, "Not a websocket handshake", 400)
		//如果错误，随便返回一些数据，以防框架报错
		respone_json := Reg_Log_Type{PARA_ERROR, INVALID, INVALID}
		this.Data["json"] = &respone_json
		this.ServeJson();
		return
	} else if err != nil {
		beego.Error("Cannot setup WebSocket connection:", err)
		//如果错误，随便返回一些数据，以防框架报错
		respone_json := Reg_Log_Type{PARA_ERROR, INVALID, INVALID}
		this.Data["json"] = &respone_json
		this.ServeJson();
		return
	}
		Join(ws, string(mac))      //设备加入到连接池中
		//defer Leave(string(mac))
		//ws.SetReadDeadline()
		// Message receive loop.
		for {
			_, p, err := ws.ReadMessage()
			if err != nil {
				//如果错误，随便返回一些数据，以防框架报错
				beego.Error("websocket read err:", err,"mac:",mac)
				Leave(string(mac))
				respone_json := Reg_Log_Type{PARA_ERROR, INVALID, INVALID}
				this.Data["json"] = &respone_json
				this.ServeJson();
				return
			}
			var data REQ_RESP_Type
			//fmt.Println("ss data",string(p))
			err_Unmarshal := json.Unmarshal(p,&data)
			if err_Unmarshal != nil{
				//如果错误，随便返回一些数据，以防框架报错
				beego.Error("json Unmarshal err:", err,"mac:",mac)
				fmt.Println("err json data",string(p))
				//ws.Close()
				//respone_json := Reg_Log_Type{PARA_ERROR, INVALID, INVALID}
				//this.Data["json"] = &respone_json
				//this.ServeJson();
				//return
			}else {


				if (SwitchModel(data, ws) == false) {
					//如果错误，随便返回一些数据，以防框架报错
					Leave(string(mac))
					beego.Error("websocket lose:", err, "mac", mac)
					respone_json := Reg_Log_Type{PARA_ERROR, INVALID, INVALID}
					this.Data["json"] = &respone_json
					this.ServeJson();
					return
				}
			}

			//publish <- newEvent(models.EVENT_MESSAGE, uname, string(p))
		}
	Leave(string(mac))
	//如果错误，随便返回一些数据，以防框架报错
	beego.Error("websocket lose:", err,mac)
	respone_json := Reg_Log_Type{PARA_ERROR, INVALID, INVALID}
	this.Data["json"] = &respone_json
	this.ServeJson();
}
//根据设备与服务通信数据分类处理
func SwitchModel(data REQ_RESP_Type,ws *websocket.Conn)(status bool){
	switch data.Model {
	case DEVICE_CONN :         //开关发起websocket连接
		fmt.Println("设备发起连接")
		fmt.Println("mac:",data.Mac)
		fmt.Println("时间：",time.Now())
		respone_data ,err := json.Marshal(REQ_RESP_Type{RespCode:INVALID,Mac:data.Mac,Model:DEVICE_CONN,DeviceType:data.DeviceType,IP:INVALIDS,Port:INVALID,ProductName:INVALIDS,TimeScale:INVALID,IRFRQ:INVALID,OpType:INVALIDS,Mask:INVALID})

		if err != nil {				//解析错误
				beego.Error("Fail to marshal event:", err)
				return
		}
		if err := ws.WriteMessage(websocket.TextMessage,respone_data ); err != nil {
				return false
		}

	case DEVICE_HEART:		//接收心跳包心跳包
		fmt.Println("心跳包")
		b, _ := json.Marshal(data)
		fmt.Println(string(b))
		ResponeHeart(data)
		if(!isDeviceExist(data.Mac)) {
			Join(ws, string(data.Mac))
		}else{
			if data.DeviceType == 1 {
				UpdateTemperature(data.Mac, data.Mask,time.Now().Unix())
				fmt.Println("湿度:", data.Mask/256, "温度:", data.Mask%256)
			}else {
				fmt.Println("data", data)
				fmt.Println("开关状态:", data.Mask,"渐亮渐灭",data.OpType)
				UpdateSwitchStatus(data.Mac, data,time.Now().Unix())
			}
		}

		//return true
	case CHECK_DEVICE_STATUS:                  //检查设备的状态
//		fmt.Println("CHECK_DEVICE_STATUS")
		//Send_change_status(data)
	case SET_DEVICE_STATUS:                  //检查设备的状态
		//		fmt.Println("CHECK_DEVICE_STATUS")
		UpdateSwitchStatus(data.Mac,data,time.Now().Unix())
	case SET_REMOTE_STATUS:						//改变开关的状态
//		fmt.Println("SET_REMOTE_STATUS")
		Send_change_status(data)
	}
	return true
}

func SendData(){

}
